package com.github.anastr.speedviewlib;
import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Matrix;
import android.graphics.Paint;
import android.graphics.Path;
import android.graphics.RadialGradient;
import android.graphics.RectF;
import android.graphics.Shader;
import android.graphics.SweepGradient;
import android.graphics.Typeface;
import android.util.AttributeSet;
import com.github.anastr.speedviewlib.base.Speedometer;
import com.github.anastr.speedviewlib.components.Indicators.SpindleIndicator;
import com.github.anastr.speedviewlib.base.SpeedometerDefault;
/**
* this Library build By Anas Altair
* see it on <a href="https://github.com/anastr/SpeedView">GitHub</a>
*/
public class PointerSpeedometer extends Speedometer {
private Path markPath = new Path();
private Paint speedometerPaint = new Paint(Paint.ANTI_ALIAS_FLAG),
pointerPaint = new Paint(Paint.ANTI_ALIAS_FLAG),
pointerBackPaint = new Paint(Paint.ANTI_ALIAS_FLAG),
circlePaint = new Paint(Paint.ANTI_ALIAS_FLAG),
markPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
private RectF speedometerRect = new RectF();
private int speedometerColor = Color.parseColor("#eeeeee")
, pointerColor = Color.WHITE;
public PointerSpeedometer(Context context) {
this(context, null);
}
public PointerSpeedometer(Context context, AttributeSet attrs) {
this(context, attrs, 0);
}
public PointerSpeedometer(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
init();
initAttributeSet(context, attrs);
}
@Override
protected void defaultValues() {
super.setTextColor(Color.WHITE);
super.setSpeedTextColor(Color.WHITE);
super.setUnitTextColor(Color.WHITE);
super.setSpeedTextSize(dpTOpx(24f));
super.setUnitTextSize(dpTOpx(11f));
super.setSpeedTextTypeface(Typeface.create(Typeface.DEFAULT, Typeface.BOLD));
}
@Override
protected SpeedometerDefault getSpeedometerDefault() {
SpeedometerDefault speedometerDefault = new SpeedometerDefault();
speedometerDefault.indicator = new SpindleIndicator(getContext())
.setIndicatorWidth(dpTOpx(16f))
.setIndicatorColor(Color.WHITE);
speedometerDefault.backgroundCircleColor = Color.parseColor("#48cce9");
speedometerDefault.speedometerWidth = dpTOpx(10f);
return speedometerDefault;
}
private void init() {
speedometerPaint.setStyle(Paint.Style.STROKE);
speedometerPaint.setStrokeCap(Paint.Cap.ROUND);
markPaint.setStyle(Paint.Style.STROKE);
markPaint.setStrokeCap(Paint.Cap.ROUND);
markPaint.setStrokeWidth(dpTOpx(2));
circlePaint.setColor(Color.WHITE);
}
private void initAttributeSet(Context context, AttributeSet attrs) {
if (attrs == null) {
initAttributeValue();
return;
}
TypedArray a = context.getTheme().obtainStyledAttributes(attrs, R.styleable.PointerSpeedometer, 0, 0);
speedometerColor = a.getColor(R.styleable.PointerSpeedometer_sv_speedometerColor, speedometerColor);
pointerColor = a.getColor(R.styleable.PointerSpeedometer_sv_pointerColor, pointerColor);
circlePaint.setColor(a.getColor(R.styleable.PointerSpeedometer_sv_centerCircleColor, circlePaint.getColor()));
a.recycle();
initAttributeValue();
}
private void initAttributeValue() {
pointerPaint.setColor(pointerColor);
}
@Override
protected void onSizeChanged(int w, int h, int oldW, int oldH) {
super.onSizeChanged(w, h, oldW, oldH);
float risk = getSpeedometerWidth() *.5f + dpTOpx(8) + getPadding();
speedometerRect.set(risk, risk, getSize() -risk, getSize() -risk);
updateRadial();
updateBackgroundBitmap();
}
private void initDraw() {
speedometerPaint.setStrokeWidth(getSpeedometerWidth());
speedometerPaint.setShader(updateSweep());
markPaint.setColor(getMarkColor());
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
initDraw();
canvas.drawArc(speedometerRect, getStartDegree(), getEndDegree()- getStartDegree(), false, speedometerPaint);
canvas.save();
canvas.rotate(90 + getDegree(), getSize() *.5f, getSize() *.5f);
canvas.drawCircle(getSize() *.5f, getSpeedometerWidth() *.5f + dpTOpx(8) + getPadding()
, getSpeedometerWidth() *.5f + dpTOpx(8), pointerBackPaint);
canvas.drawCircle(getSize() *.5f, getSpeedometerWidth() *.5f + dpTOpx(8) + getPadding()
, getSpeedometerWidth() *.5f + dpTOpx(1), pointerPaint);
canvas.restore();
drawSpeedUnitText(canvas);
drawIndicator(canvas);
int c = getCenterCircleColor();
circlePaint.setColor(Color.argb(120, Color.red(c), Color.green(c), Color.blue(c)));
canvas.drawCircle(getSize() *.5f, getSize() *.5f, getWidthPa()/14f, circlePaint);
circlePaint.setColor(c);
canvas.drawCircle(getSize() *.5f, getSize() *.5f, getWidthPa()/22f, circlePaint);
drawNotes(canvas);
}
@Override
protected void updateBackgroundBitmap() {
Canvas c = createBackgroundBitmapCanvas();
initDraw();
markPath.reset();
markPath.moveTo(getSize() *.5f, getSpeedometerWidth() + dpTOpx(8) + dpTOpx(4) + getPadding());
markPath.lineTo(getSize() *.5f, getSpeedometerWidth() + dpTOpx(8) + dpTOpx(4) + getPadding() + getSize()/60);
c.save();
c.rotate(90f + getStartDegree(), getSize() *.5f, getSize() *.5f);
float everyDegree = (getEndDegree() - getStartDegree()) * .111f;
for (float i = getStartDegree(); i < getEndDegree()-(2f*everyDegree); i+=everyDegree) {
c.rotate(everyDegree, getSize() *.5f, getSize() *.5f);
c.drawPath(markPath, markPaint);
}
c.restore();
drawDefMinMaxSpeedPosition(c);
}
private SweepGradient updateSweep() {
int startColor = Color.argb(150, Color.red(speedometerColor), Color.green(speedometerColor), Color.blue(speedometerColor));
int color2 = Color.argb(220, Color.red(speedometerColor), Color.green(speedometerColor), Color.blue(speedometerColor));
int color3 = Color.argb(70, Color.red(speedometerColor), Color.green(speedometerColor), Color.blue(speedometerColor));
int endColor = Color.argb(15, Color.red(speedometerColor), Color.green(speedometerColor), Color.blue(speedometerColor));
float position = getOffsetSpeed() * (getEndDegree() - getStartDegree())/360f;
SweepGradient sweepGradient = new SweepGradient(getSize() *.5f, getSize() *.5f
, new int[]{startColor, color2, speedometerColor, color3, endColor, startColor}
, new float[]{0f, position *.5f, position, position, .99f, 1f});
Matrix matrix = new Matrix();
matrix.postRotate(getStartDegree(), getSize() *.5f, getSize() *.5f);
sweepGradient.setLocalMatrix(matrix);
return sweepGradient;
}
private void updateRadial() {
int centerColor = Color.argb(160, Color.red(pointerColor), Color.green(pointerColor), Color.blue(pointerColor));
int edgeColor = Color.argb(10, Color.red(pointerColor), Color.green(pointerColor), Color.blue(pointerColor));
RadialGradient pointerGradient = new RadialGradient(getSize() *.5f, getSpeedometerWidth() *.5f + dpTOpx(8) + getPadding()
, getSpeedometerWidth() *.5f + dpTOpx(8), new int[]{centerColor, edgeColor}
, new float[]{.4f, 1f}, Shader.TileMode.CLAMP);
pointerBackPaint.setShader(pointerGradient);
}
public int getSpeedometerColor() {
return speedometerColor;
}
public void setSpeedometerColor(int speedometerColor) {
this.speedometerColor = speedometerColor;
invalidate();
}
public int getPointerColor() {
return pointerColor;
}
public void setPointerColor(int pointerColor) {
this.pointerColor = pointerColor;
pointerPaint.setColor(pointerColor);
updateRadial();
invalidate();
}
public int getCenterCircleColor() {
return circlePaint.getColor();
}
/**
* change the color of the center circle (if exist),
* <b>this option is not available for all Speedometers</b>.
* @param centerCircleColor new color.
*/
public void setCenterCircleColor(int centerCircleColor) {
circlePaint.setColor(centerCircleColor);
if (!isAttachedToWindow())
return;
invalidate();
}
/**
* this Speedometer doesn't use this method.
* @return {@code Color.TRANSPARENT} always.
*/
@Deprecated
@Override
public int getLowSpeedColor() {
return Color.TRANSPARENT;
}
/**
* this Speedometer doesn't use this method.
* @param lowSpeedColor nothing.
*/
@Deprecated
@Override
public void setLowSpeedColor(int lowSpeedColor) {
}
/**
* this Speedometer doesn't use this method.
* @return {@code Color.TRANSPARENT} always.
*/
@Deprecated
@Override
public int getMediumSpeedColor() {
return Color.TRANSPARENT;
}
/**
* this Speedometer doesn't use this method.
* @param mediumSpeedColor nothing.
*/
@Deprecated
@Override
public void setMediumSpeedColor(int mediumSpeedColor) {
}
/**
* this Speedometer doesn't use this method.
* @return {@code Color.TRANSPARENT} always.
*/
@Deprecated
@Override
public int getHighSpeedColor() {
return Color.TRANSPARENT;
}
/**
* this Speedometer doesn't use this method.
* @param highSpeedColor nothing.
*/
@Deprecated
@Override
public void setHighSpeedColor(int highSpeedColor) {
}
}